<template>
  <div class="app-container-flex">
    <NewFullScreen
      v-model="showDialog"
      :title="title"
      :need-return="false"
      :btn-list="fullInfo.btnList"
      :newFullScreenClass="newFullScreenClass"
    >
      <template v-slot:full-button>
        <ScanInputBox
          :query="scanInfo.query"
          :api="scanInfo.api"
          type="3"
          style="margin-right: 10px"
          @callback="onCallBackScanData"
        />
        <el-button
          :disabled="!tableInfo.list?.length"
          v-if="!orderId && $permission('assetReceiving:saveAndSubmit')"
          @click="saveAndSubmit"
        >
          保存并提交
        </el-button>
        <el-button :disabled="!tableInfo.list.length" @click="save"
          >保存</el-button
        >
      </template>
      <!-- 主表信息 -->
      <div id="table-list">
        <div class="model-panel">
          <div class="model-panel-title">
            <p>{{ $t('basic_information') }}</p>
          </div>
          <div class="model-panel-body">
            <!-- form -->
            <page-form
              class="paddingBox order-model-formBox flex_wrap_start_start"
              v-model:ref-obj="formInfo.ref"
              :disabled="formInfo.disabled"
              :data="formInfo.data"
              :field-list="formInfo.fieldList"
              :rules="formInfo.rules"
              :label-width="formInfo.labelWidth"
            >
              <template v-slot:form-deptName>
                <el-input
                  v-model="formInfo.data.deptName"
                  class="not-br not-mongolia"
                  type="input"
                  :disabled="true"
                  placeholder="请选择部门"
                >
                  <template #append>
                    <el-icon @click="openDepotWindow"><MoreFilled /></el-icon>
                  </template>
                </el-input>
              </template>
            </page-form>
          </div>

          <!-- 明细信息 -->
          <div id="table-box" class="model-panel">
            <div class="model-panel-title">
              <Tooltip :text="$t('detailInfo')"></Tooltip>
            </div>
            <div class="model-panel-body">
              <!-- 条件栏 -->
              <new-page-filter :filter-btn="filterInfo.btnList">
                <template v-slot:filter-addProduct>
                  <el-button @click="addProduct">添加资产</el-button>
                </template>
                <template v-slot:filter-remove>
                  <el-button
                    :disabled="!tableInfo.selections.length"
                    @click="remove"
                  >
                    删除资产
                  </el-button>
                </template>
              </new-page-filter>
              <!-- 表格 -->
              <el-form ref="tableForm" :model="tableInfo" style="width: 100%">
                <page-table
                  :refresh="tableInfo.refresh"
                  :init-curpage="tableInfo.initCurpage"
                  v-model:data="tableInfo.data"
                  :pager="false"
                  :summary="true"
                  :summary-field-list="tableInfo.summaryFieldList"
                  :tab-index="true"
                  :check-box="true"
                  :query="filterInfo.query"
                  :field-list="tableInfo.fieldList"
                  :handle="tableInfo.handle"
                  :row-class-name="tableRowClassName"
                  :isDynamic="false"
                  @handleEvent="handleEvent"
                >
                  <template v-slot:col-qty="scope">
                    <el-input-number
                      v-model="scope.row.qty"
                      controls-position="right"
                      style="width: 100%"
                      :min="0"
                      :max="scope.row.pendReceiveQty"
                      :precision="0"
                      :step="1"
                    />
                  </template>
                  <template v-slot:col-refuseQty="scope">
                    <el-input-number
                      v-model="scope.row.refuseQty"
                      controls-position="right"
                      style="width: 100%"
                      :min="0"
                      :max="scope.row.pendReceiveQty"
                      :precision="0"
                      :step="1"
                    />
                  </template>
                  <template v-slot:col-price="scope">
                    <el-form-item
                      :prop="`data.${scope.$index}.price`"
                      :rules="
                        scope.$index >= 0
                          ? [
                              {
                                validator: $validate.positive,
                                trigger: 'blur',
                              },
                            ]
                          : []
                      "
                    >
                      <el-input-number
                        v-model="scope.row.price"
                        controls-position="right"
                        style="width: 100%; margintop: 18px"
                        :min="0"
                        :max="999999999999999"
                        :precision="assets_price_precision"
                        :step="1"
                      />
                    </el-form-item>
                  </template>
                </page-table>
              </el-form>
            </div>
          </div>
        </div>
      </div>
    </NewFullScreen>
    <select-dept
      v-if="selectDeptInfo.visible"
      v-model:show-dialog="selectDeptInfo.visible"
      :query="selectDeptInfo.query"
      :check-box="false"
      :save-empty="true"
      :highlight-row="true"
      @callback="selectDeptCallback"
    />
    <SelectEquipmentArchives
      v-if="equipmentInfo.visible"
      v-model:show-dialog="equipmentInfo.visible"
      :query="equipmentInfo.query.queryMap"
      :query-params="equipmentInfo.queryParams"
      :api="equipmentInfo.api"
      :table-key="equipmentInfo.tableKey"
      @callback="equipmentBack"
    />
  </div>
</template>

<script setup name="receivingModify">
import {
  createReceive,
  createReceiveAndSave,
  updateReceive,
  getReceiveById,
  getReceiveDetailsAll,
  getReceivingDetailByDeliver,
  getReceivingIndividualByDeliver,
  receiveScan,
} from '@/api/asset'
import { getOrganizationPage } from '@/api/base'
import { getAssetDepotsDefault } from '@/api/core'
import { getCustomizeSetting } from '@/api/customize'
import ScanInputBox from './ScanInputBox'
import _ from 'lodash'

const { proxy } = getCurrentInstance()
const emits = defineEmits()
const props = defineProps([
  'visible',
  'deliverId',
  'orderId',
  'title',
  'receivingSourceOrderNo',
])

const loading = ref(false)
const listPage = ref(0)
const scrollTop = ref(0)
const box = ref(undefined)
const assets_price_precision = ref(
  proxy.$store.state.permission.systemConfig.assets_price_precision
)
const formRefs = ref([])
const scanInfo = ref({
  query: {
    customizeUserVO: {},
    queryMap: {
      productCode: {
        queryType: 'EQUALS',
        queryCategory: 'AND',
        value: '',
      },
    },
    queryParams: {
      deliverId: '',
      receiveId: '',
      receiveOrderSourceType: 18,
      pendReceiveGtZero: true,
    },
  },
  api: receiveScan,
})
//full组件信息
const fullInfo = ref({
  visible: false,
  btnList: [{ label: '返回', event: returnBank, show: true }],
})
const formInfo = ref({
  ref: null,
  data: {
    deptName: '',
    deptId: '',
  },
  fieldList: [
    {
      label: '发货单号',
      value: 'deliverOrderNo',
      type: 'input',
      disabled: true,
    },
    {
      label: '采购单号',
      value: 'purchOrderNo',
      type: 'input',
      disabled: true,
    },
    {
      label: '供应商',
      value: 'supplierName',
      type: 'input',
      disabled: true,
    },

    {
      label: '发票单号',
      value: 'invoiceNumber',
      type: 'input',
    },
    // {
    //   label: '货单号',
    //   value: 'waybillNumber',
    //   type: 'input',
    // },
    { label: '收货部门', value: 'deptName', type: 'slot' },
    {
      label: '收货联系人',
      value: 'receivingContacts',
      type: 'input',
    },
    {
      label: '联系人电话',
      value: 'receivingPhone',
      type: 'input',
    },
    {
      label: '备注',
      value: 'remark',
      type: 'textarea',
    },
  ],
  rules: {
    deptName: [{ required: true, message: '请选择部门', target: 'change' }],
    receivingPhone: [{ validator: proxy.$validate.cellphone, trigger: 'blur' }],
  },
  labelWidth: '120px',
})
// 过滤相关配置
const filterInfo = ref({
  query: {
    customizeUserVO: {},
    queryMap: {
      orderId: {
        queryType: 'EQUALS',
        queryCategory: 'AND',
        value: '',
      },
    },
    queryParams: {
      receiveAll: true,
      deliverId: '',
      receiveId: '',
    },
  },
  btnList: [
    { label: '添加资产', type: 'slot', value: 'addProduct' },
    { label: '删除资产', type: 'slot', value: 'remove' },
  ],
})
// 表格相关
const tableInfo = ref({
  refresh: 1,
  initCurpage: 1,
  data: [],
  selections: [],
  summaryFieldList: [
    { value: 'qty', formatter: proxy.$fn.qtyFormatter },
    { value: 'price', show: 'false' },
    { value: 'sumAmount', formatter: proxy.$fn.TripartiteMethod },
  ],
  fieldList: [],
  handle: {
    fixed: 'right',
    label: '操作',
    width: '100',
    btList: [
      {
        label: '删除',
        popconfirmText: '删除后将改变数据,是否继续？',
        event: remove,
        show: proxy.$permission('receiving:del'),
      },
    ],
  },
  list: [],
})
const selectDeptInfo = ref({
  visible: false,
  isDept: '',
  query: {
    deptAuth: 'id',
    status: '1',
  },
})
const selectUserInfo = ref({
  visible: false,
  query: {
    status: 1,
    idNotIn: '',
  },
})
const equipmentInfo = ref({
  visible: false,
  api: getReceivingIndividualByDeliver,
  tableKey:
    'assetReceivingAddAsset-com.slip.spd.entity.vo.asset.AssetReceivingOrderDetailVO',
  query: {
    queryMap: {
      type: {
        asTbName: 'core_product_new',
        columnName: '`type`',
        queryType: 'EQUALS',
        queryCategory: 'AND',
        value: '',
      },
      status: {
        asTbName: 'core_product_new',
        columnName: '`status`',
        queryType: 'EQUALS',
        queryCategory: 'AND',
        value: '',
      },
      productId: {
        queryType: 'NOT_IN',
        queryCategory: 'AND',
        value: '',
      },
    },
  },
  queryParams: {
    deliverId: '',
    receiveId: '',
    pendReceiveGtZero: true,
  },
})
const oldDataIndex = ref(-1)
const newFullScreenClass = ref('scrollY' + new Date().getTime())

const showDialog = computed({
  get() {
    return props.visible
  },
  set(newValue) {
    emits('update:visible', newValue) // 更新父组件visible
  },
})
watch(
  () => tableInfo.value.data,
  (val) => {
    if (val.length) {
      val.forEach((item, index) => {
        item.tableIndex = index + 1
      })
    }
  },
  {
    deep: true,
  }
)
watch(
  () => tableInfo.value.list,
  (val) => {
    if (val.length) {
      val.forEach((item) => {
        item.sumAmount = proxy.$fn.accMul(item.price || 0, item.qty || 0)
      })
    }
  },
  {
    deep: true,
  }
)

onMounted(() => {
  formRefs.value = [proxy.$refs['tableForm'], formInfo.value.ref]
  box.value = document.getElementsByClassName(newFullScreenClass.value)[0]
  box.value && box.value.addEventListener('scroll', throttle(handleScroll, 30))
})
onBeforeUnmount(() => {
  box.value &&
    box.value.removeEventListener('scroll', throttle(handleScroll, 30))
})

setData()
function setData() {
  let obj = {
    qty: {
      label: '数量',
      value: 'qty',
      type: 'slot',
      minWidth: '250px',
    },
    refuseQty: {
      label: '拒收数',
      value: 'refuseQty',
      type: 'slot',
      minWidth: '250px',
    },
    price: {
      label: '单价',
      value: 'price',
      type: 'slot',
      minWidth: '250px',
    },
  }
  tableInfo.value.fieldList = Object.values({
    ...proxy.$fn.deepClone(proxy.$fieldfList.FieldList),
    ...obj,
  })
  getCustomize()
  getScanCustomize()
}
function handleScroll() {
  // 获取eagleMapContainer的真实高度
  const box = document.getElementsByClassName(newFullScreenClass.value)[0]
  const boxHeight = box.offsetHeight
  // 获取table_list的真实高度（浮动内容的真实高度）
  const tableHeight = document.getElementById('table-list').offsetHeight
  const tableDom = document.getElementById('table-box')
  // boxHeight和滑块浮动的高度相差小于50 && 不在加载中 && 不是最后一页
  if (
    tableHeight - (box.scrollTop + boxHeight) < 50 &&
    !loading.value &&
    listPage.value + 1 < tableInfo.value.data.length / 50
  ) {
    // 第一次触发时，记录滑块高度
    // data里scrollTop，listPage默认为0
    if (!scrollTop.value) {
      scrollTop.value = box.scrollTop
    }
    // 触发下拉加载更多
    queryMoreStat(true, tableHeight, boxHeight)
  } else if (box.scrollTop <= tableDom.offsetTop + 200 && !loading.value) {
    // 如果滑块上拉到顶部，则向上加载50条
    queryMoreStat(false, tableHeight, boxHeight)
  }
}
function queryMoreStat(type, tableHeight, boxHeight) {
  loading.value = true
  // 触底加载
  const tableData = tableInfo.value.data
  if (type) {
    listPage.value = listPage.value + 1
    const centerPage = listPage.value * 50
    const startPage = centerPage >= 50 ? centerPage - 50 : centerPage
    const endPage = centerPage + 50
    const newList = tableData.slice(startPage, endPage)
    if (listPage.value > 0) {
      const box = document.getElementsByClassName(newFullScreenClass.value)[0]
      // 视图跳到触发的数据，补回50的高度差值
      box.scrollTop = scrollTop.value - 50
    }
    tableInfo.value.list = newList
  } else {
    // 置顶加载
    if (listPage.value > 0) {
      listPage.value = listPage.value - 1
      const centerPage = listPage.value * 50
      const startPage = centerPage >= 50 ? centerPage - 50 : centerPage
      const endPage = centerPage + 50
      const newList = tableData.slice(startPage, endPage)
      if (listPage.value > 0) {
        const tableDom = document.getElementById('table-box')
        const box = document.getElementsByClassName(newFullScreenClass.value)[0]
        // box.scrollTop = tableHeight - scrollTop.value - boxHeight

        box.scrollTop = tableDom.offsetTop + 220
      }
      tableInfo.value.list = newList
    } else {
      tableInfo.value.list = tableData.slice(0, 50)
    }
  }
  proxy.$nextTick(() => {
    loading.value = false
  })
}
function throttle(fn, delay) {
  let timer = null,
    startTime = new Date()
  return function () {
    let curTime = new Date()
    let remaining = delay - (curTime - startTime)
    clearTimeout(timer)
    if (remaining <= 0) {
      startTime = new Date()
      fn.apply(proxy, arguments)
    } else {
      timer = setTimeout(fn, remaining)
    }
  }
}
function openDepotWindow() {
  //添加部门
  selectDeptInfo.value.visible = true
}
function selectDeptCallback(row) {
  //部门返回
  if (row && row.id) {
    formInfo.value.data['deptId'] = row.id
    formInfo.value.data['deptName'] = row.name
  } else {
    formInfo.value.data['deptId'] = ''
    formInfo.value.data['deptName'] = ''
  }
}
function onCallBackScanData(data, callback) {
  //扫码返回
  let curIndex = 0
  data.qty = data.pendReceiveQty
  if (tableInfo.value.data.length) {
    let index = tableInfo.value.data.findIndex(
      (item) => item.productCode === data.productCode
    )
    if (index > -1) {
      tableInfo.value.data.forEach((item) => {
        item.isChoice = false
        if (item.productCode === data.productCode) {
          item.isChoice = true
        }
      })
      scrollTable(curIndex, index)
      callback(false)
    } else {
      tableInfo.value.data.forEach((item) => {
        item.isChoice = false
      })
      tableInfo.value.data.unshift(data)
      scrollTable(curIndex, 0)
      callback(true)
    }
  } else {
    tableInfo.value.data.unshift(data)
    scrollTable(curIndex, 0)
    callback(true)
  }
}
function scrollTable(curIndex, itemIndex) {
  curIndex = itemIndex
  proxy.listPage = Math.floor(curIndex / 50)
  const centerPage = proxy.listPage * 50
  const startPage = centerPage >= 50 ? centerPage - 50 : centerPage
  const endPage = centerPage + 50
  tableInfo.value.list = tableInfo.value.data.slice(startPage, endPage)
  oldDataIndex.value = curIndex
}
function addProduct() {
  let ids = ''
  if (tableInfo.value.data.length) {
    ids = tableInfo.value.data.map((item) => item.productId).toString()
  }
  equipmentInfo.value.query.queryMap.productId.value = ids
  if (props.deliverId) {
    equipmentInfo.value.queryParams.deliverId = props.deliverId
  } else if (props.orderId) {
    equipmentInfo.value.queryParams.deliverId =
      formInfo.value.data.deliverOrderId
    equipmentInfo.value.queryParams.receiveId = props.orderId
  }
  equipmentInfo.value.visible = true
}
function equipmentBack(data) {
  data.forEach((item) => {
    item.qty = item.pendReceiveQty
  })
  tableInfo.value.data = data.concat(tableInfo.value.data)
  tableInfo.value.data.forEach((item) => {
    item.isChoice = false
  })
  tableInfo.value.list = tableInfo.value.data.slice(0, 50)
}
function handleEvent(event, data) {
  switch (event) {
    case 'tableCheck':
      tableInfo.value.selections = [...data]
      break
  }
}
function remove(selectRow = undefined) {
  if (selectRow && selectRow.id) {
    tableInfo.value.list = tableInfo.value.list.filter(
      (row) => row !== selectRow
    )
    tableInfo.value.data = tableInfo.value.data.filter(
      (row) => row !== selectRow
    )
  } else {
    proxy
      .$confirm('删除后将改变数据,是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(() => {
        tableInfo.value.list = tableInfo.value.list.filter(
          (row) => !tableInfo.value.selections.includes(row)
        )
        tableInfo.value.data = tableInfo.value.data.filter(
          (row) => !tableInfo.value.selections.includes(row)
        )
      })
  }
  oldDataIndex.value = -1
}
function tableRowClassName({ row }) {
  if (row.isChoice) {
    return 'success-row'
  }
  return ''
}
function getDepotsDefaults() {
  //查询默认部门
  getAssetDepotsDefault().then((resp) => {
    if (resp && resp.success) {
      let data = resp.data
      if (data && data.deptId) {
        formInfo.value.data['deptName'] = data.deptName
        formInfo.value.data['deptId'] = data.deptId
      }
    }
  })
  proxy.$nextTick(() => {
    formInfo.value.ref.clearValidate('deptName')
  })
}
function saveAndSubmit() {
  save(true)
}
function save(isSaveAndSubmit) {
  proxy.$fn.checkForm(formRefs.value).then(() => {
    let api = props.orderId
      ? updateReceive
      : isSaveAndSubmit === true
      ? createReceiveAndSave
      : createReceive
    let data = formInfo.value.data
    let mergeDetails = proxy.$fn
      .deepClone(tableInfo.value.data)
      .filter((row) => row.qty > 0 || row.refuseQty > 0)
    if (!mergeDetails.length) {
      proxy.$message({
        duration: 3500,
        type: 'warning',
        showClose: true,
        message: '请添加有效的资产',
      })
      return
    }
    let commonName = mergeDetails
      .filter(
        (item) =>
          proxy.$fn.accAdd(item.qty, item.refuseQty) > item.pendReceiveQty
      )
      .map((item) => item.commonName)
    if (commonName.length) {
      proxy.$alert(
        `产品【${commonName}】的接收数与拒收数之和不能大于待收货数量`,
        '操作提示',
        {
          confirmButtonText: '确定',
          dangerouslyUseHTMLString: true,
        }
      )
      return
    }
    mergeDetails.forEach((item) => {
      item.calcQty = item.qty
      item.refuseCalcQty = item.refuseQty
    })
    data.mergeDetails = mergeDetails
    data.receiveOrderSourceType = 18
    if (props.receivingSourceOrderNo) {
      data.receivingSourceOrderNo = props.receivingSourceOrderNo
    }
    data.receiveAll = true
    api(data).then((res) => {
      if (res && res.success) {
        showDialog.value = false
        emits('returnModify', false)
      }
    })
  })
}
function returnBank() {
  showDialog.value = false
  emits('returnModify')
}
function getMain() {
  getReceiveById(props.orderId).then((res) => {
    if (res && res.success) {
      filterInfo.value.query.queryParams.deliverId = res.data.deliverOrderId
      filterInfo.value.query.queryParams.receiveId = props.orderId
      formInfo.value.data = res.data
      formInfo.value.data = res.data
      getList()
      scanInfo.value.query.queryParams.deliverId = res.data.deliverOrderId
      scanInfo.value.query.queryParams.receiveId = props.orderId
    }
  })
}
function getMainByDeliver() {
  let query = proxy.$fn.deepClone(filterInfo.value.query)
  query.queryParams.pendReceiveGtZero = true
  getReceivingDetailByDeliver(query).then((res) => {
    if (res && res.success) {
      let data = res.data
      if (data.mergeDetails && data.mergeDetails.length) {
        data.mergeDetails.forEach((item) => {
          item.qty = item.pendReceiveQty
        })
        tableInfo.value.data = data.mergeDetails
        tableInfo.value.list = tableInfo.value.data.slice(0, 50)
      }
      formInfo.value.data = data
      scanInfo.value.query.queryParams.deliverId = props.deliverId
      getDepotsDefaults()
    }
  })
}
function getList() {
  let query = proxy.$fn.deepClone(filterInfo.value.query)
  query.queryParams = {}
  getReceiveDetailsAll(query).then((res) => {
    if (res && res.success) {
      tableInfo.value.data = res.data
      tableInfo.value.list = tableInfo.value.data.slice(0, 50)
    }
  })
}
function getCustomize() {
  let param = {
    tableKey:
      'assetReceivingModifyByDeliver-com.slip.spd.entity.vo.asset.AssetReceivingOrderDetailVO',
  }
  getCustomizeSetting(param).then((res) => {
    if (res && res.success) {
      let data = res.data
      tableInfo.value.fieldList = proxy.$fn.setFieldList(
        tableInfo.value.fieldList,
        data.detail
      )
      filterInfo.value.query.customizeUserVO = data
      if (props.deliverId) {
        filterInfo.value.query.queryMap.orderId.value = props.deliverId
        filterInfo.value.query.queryParams.deliverId = props.deliverId
        getMainByDeliver()
      } else if (props.orderId) {
        filterInfo.value.query.queryMap.orderId.value = props.orderId
        getMain()
      }
    }
  })
}
function getScanCustomize() {
  let param = {
    tableKey:
      'assetReceivingAddAsset-com.slip.spd.entity.vo.asset.AssetReceivingOrderDetailVO',
  }
  getCustomizeSetting(param).then((res) => {
    if (res && res.success) {
      let data = res.data
      scanInfo.value.query.customizeUserVO = data
    }
  })
}
</script>

<style scoped lang="scss"></style>
